package cate.game.role.task.conditiontask;

import cate.common.table.conditiontask.ConditionRow;
import cate.common.table.conditiontask.ConditionTIdRow;
import cate.game.role.RoleDependent;
import cate.game.role.Role;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteField;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public abstract class ConditionFuncPO<E extends ConditionTIdRow> extends RoleDependent {

    @JsonIgnore
    @NoteField(value = "完成后操作id(tid),条件(conditionId)")
    public Map<Integer, ConditionPO> conditionMap;

    @Override
    public void initialize(Role role) {
        super.initialize(role);
        if (conditionMap == null) {
            conditionMap = new HashMap<>();
        }
        if (!conditionMap.isEmpty()) {
            conditionMap.forEach((key, value) -> value.initialize(role));
            conditionMap.entrySet().removeIf(item -> item.getValue().getRow() == null);
        }

        checkCondition();
    }

    public void checkCondition() {
        List<Integer> tids = checkSelfCondition();

        conditionMap.entrySet().removeIf(entry -> !tids.contains(entry.getKey()));

        //添加进入没有的 以及 替换掉改变条件的
        if (tids != null && !tids.isEmpty()) {
            for (int tid : tids) {
                ConditionPO condition = conditionMap.get(tid);
                if (condition == null || condition.conditionId != getRow(tid).conditionId) {
                    E row = getRow(tid);
                    if (row.conditionId == 0) {
                        continue;
                    }
                    condition = new ConditionPO(role, row.tid, row.conditionId);
                    conditionMap.put(tid, condition);
                }
            }
        }
    }

    /**
     * 获取处理结果的row
     *
     * @param tid
     * @return
     */
    protected abstract E getRow(int tid);

    /**
     * 根据需要条件更新自己的conditionMap
     *
     * @return
     */
    protected abstract List<Integer> checkSelfCondition();


    /**
     * 推送条件检测
     *
     * @param event
     * @param param
     * @param value
     * @param add
     */
    public void doRecord(int event, int param, long value, boolean add) {
        for (ConditionPO condition : conditionMap.values()) {
            ConditionRow row = condition.getRow();
            // 推送条件达成后就不再记录
            if (row != null && row.event == event && row.param == param) {
                if (condition.done) {
                    continue;
                }
                condition.setValue(value, add);
                // 完成后尝试推送礼包
                if (condition.done) {
                    doDone(condition.tId);
                }else{
                    valueChange(condition.tId);
                }
            }
        }
    }

    protected abstract void doDone(int tid);

    protected void valueChange(int tid){

    }

    public void clear() {
        conditionMap.clear();
        selfClear();
    }

    public void removeConditions(List<Integer> tids) {
        conditionMap.entrySet().removeIf(entry -> tids.contains(entry.getKey()));
    }

    protected abstract void selfClear();

    public void onDaySpan() {
        conditionMap.values().forEach(ConditionPO::onDaySpan);
        checkCondition();
    }

    public void onWeekSpan() {
        conditionMap.values().forEach(ConditionPO::onWeekSpan);
    }

    public void onMonthSpan() {
        conditionMap.values().forEach(ConditionPO::onMonthSpan);
    }

    protected boolean isDone(int tid){
        return conditionMap.get(tid) != null && conditionMap.get(tid).done;
    }
}
